﻿layui.define([], function(exports){

    function dataset(data){
        if (!(this instanceof dataset)) {
            return new dataset(data)
        }
        Object.defineProperty(this,'_data_cache',{
            enumerable: false,
            configurable: false,
            writable: false,
            value: data||{}
        })
        this.has = function (key) {
            return this._data_cache.hasOwnProperty(key);
        }
        this.get = function (key) {
            if(!key){
                return this._data_cache;
            }
            else {
                return getter.call(this,this._data_cache,key);
            }
        }

        this.set = function(){
            Array.prototype.unshift.call(arguments,'set');
            return verify.apply(this,arguments);
        }
        this.add = function(){
            Array.prototype.unshift.call(arguments,'add');
            return verify.apply(this,arguments);
        }
        this.sub = function(){
            Array.prototype.unshift.call(arguments,'sub');
            return verify.apply(this,arguments);
        }
        this.del = function(){
            Array.prototype.unshift.call(arguments,'del');
            return verify.apply(this,arguments);
        }
    }


    //t,k,v
    function verify(t,k) {
        if (!k){
            return false;
        }
        else if( t==='set' && typeof k === 'object' && !Array.isArray(k) ){
            Object.assign(this._data_cache,k);
            return this._data_cache;
        }
        else {
            Array.prototype.unshift.call(arguments,this._data_cache);
            return setter.apply(this,arguments);
        }
    }


    function getter(data,key) {
        let arr  = Array.isArray(key) ? key : String(key).split(".");
        let k = arr.shift();
        if( !isObject(data) || !data.hasOwnProperty(k) ){
            return null;
        }
        if(arr.length > 0){
            return getter.call(this,data[k],arr);
        }
        else {
            return data[k];
        }
    }
    //d,t,k,[v]
    function setter(data,type,key) {
        if( !isObject(data) ){
            return false;
        }
        let arr  = Array.isArray(key) ? key : String(key).split(".");
        let k = arr.shift();
        if(arr.length > 0){
            if(!data.hasOwnProperty(k)){
                data[k] = {};
            }
            else if(!isObject(data[k])){
                return false;
            }
            arguments[0] = data[k];
            arguments[2] = arr;
            return setter.apply(this,arguments);
        }
        else {
            arguments[2] = k;
            return update.apply(this,arguments);
        }

    }

    function isObject(o) {
        if( o === null || typeof o !== 'object'){
            return false;
        }
        else {
            return true;
        }
    }


    //args:  data,key,val,type
    //type:  -1:sub,0;set,1:add
    function update(data,type,key){
        let d,v;
        switch (type) {
            case 'del':
                delete data[key];
                break;
            case 'add':
                d = data[key] || 0;v=Number(arguments[3]);
                data[key] = d + v;
                break;
            case 'sub':
                d = data[key] || 0;v=Number(arguments[3]);
                data[key] = d - v;
                break;
            case 'set':
                if( isObject(data[key]) && isObject(arguments[3]) ){
                    Object.assign(data[key] , arguments[3])
                }
                else {
                    data[key] = arguments[3];
                }
                break;
        }

        return data[key];
    }

    exports('dataset', dataset);
});